package io.gitee.bluemiaomiao.dataanalyzebackend.config;

import io.gitee.bluemiaomiao.dataanalyzebackend.domian.Menu;
import io.gitee.bluemiaomiao.dataanalyzebackend.service.MenuRoleService;
import io.gitee.bluemiaomiao.dataanalyzebackend.service.MenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;

import java.util.Collection;
import java.util.List;

/**
 * @Author: TLang @Date: 2020/11/7
 *
 * @description: 元数据，功能为请求的url查询其权限信息并以list形式存储
 */
@Component
public class UrlFilterInvocationSecurityMetadataSource
    implements FilterInvocationSecurityMetadataSource {

  AntPathMatcher antPathMatcher = new AntPathMatcher();

  @Autowired MenuService menuService;
  @Autowired MenuRoleService menuRoleService;

  @Override
  public Collection<ConfigAttribute> getAttributes(Object o) throws IllegalArgumentException {

    // 获取 请求 url 地址
    String requestUrl = ((FilterInvocation) o).getRequestUrl();
    // 得到所有 url 和 角色 的对应关系（这里可以用缓存处理）
    List<Menu> allMenus = menuService.queryAll();
    // 如果和 请求url 匹配上 就把他存入到 Collection<ConfigAttribute> 里
    for (Menu menu : allMenus) {
      if (antPathMatcher.match(menu.getPattern(), requestUrl)) {
        // 如果匹配上就 获取到 所需的角色列表
        List<String> roles = menuRoleService.findRoleNameByMenuid(menu.getId());
        String[] strList = new String[roles.size()];
        for (int i = 0; i < strList.length; i++) {
          strList[i] = roles.get(i);
        }
        return SecurityConfig.createList(strList);
      }
    }
    // 如果都没有匹配上，我们返回默认值，这个值就像一个特殊的标识符，自定义
    return SecurityConfig.createList("ROLE_LOGIN");
  }

  @Override
  public Collection<ConfigAttribute> getAllConfigAttributes() {
    return null;
  }

  @Override
  public boolean supports(Class<?> aClass) {
    return false;
  }
}
